﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Proggy.Web.Cms.PropertyTypes;
using Proggy.Web.Cms.Core.Configuration.ConfigObjects;
using Proggy.Web.Cms.Repositories.Published;
using Proggy.Web.Cms.Core.ContentModels;
using System.Web.Mvc;
using Proggy.Web.Cms.Context;
using Proggy.Web.Cms.Cache;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using Ninject;

namespace Proggy.Web.Cms.Core.PropertyTypes
{
    /// <summary>
    /// Image picker property type
    /// </summary>
    [PropertyType("Image picker", "~/Areas/ProggyCore/Views/EditorPartials/ProggyImagePickerEditor.cshtml", RequiredConfigObjectType = typeof(ProggyImagePickerConfigObject))]
    public class ProggyImagePicker : ConfigurablePropertyTypeBase, IValidatablePropertyType, IAutoRenderPropertyType
    {
        /// <summary>
        /// Constructor for testing
        /// </summary>
        /// <param name="repo"></param>
        public ProggyImagePicker(IPublishedContentRepository repo)
        {
            this._repo = repo;
        }

        /// <summary>
        /// Constructor with fallback for setting IPublishedContentRepo
        /// </summary>
        public ProggyImagePicker()
        {

        }

        private IPublishedContentRepository _repo;

        ///// <summary>
        ///// Content repo
        ///// </summary>
        //public IPublishedContentRepository PublishedContentRepository { get; set; }

        #region methods

        /// <summary>
        /// Returns image folders
        /// </summary>
        /// <returns></returns>
        public List<ProggyFileFolderContentModel> GetImageFolders(string[] uniqueAliases)
        {
            // check
            if (this._repo == null)
            {
                try
                {
                    this._repo = DependencyResolver.Current.GetService<IPublishedContentRepository>();
                }
                catch (Exception ex)
                {
                    throw new Exception("Cannot create instance of IPublishedContentRepository: " + ex.Message);
                }
            }

            // get all folders
            var allFolders = this._repo.GetTypedPublishedContent<ProggyFileFolderContentModel>(false);

            // start folders
            IQueryable<ProggyFileFolderContentModel> folders = null;

            // get either all folders or specific
            if (uniqueAliases == null || uniqueAliases.Count() < 1)
            {
                folders = allFolders;
            }
            else
            {
                folders =
                    allFolders.Where(x =>
                        !string.IsNullOrEmpty(x.UniqueAlias) &&
                        uniqueAliases.Contains(x.UniqueAlias.ToLower())
                    );
            }


            // 
            return folders.OrderBy(x => x.Name).ToList();
        }

        /// <summary>
        /// Returns images for image folder
        /// </summary>
        /// <param name="folder"></param>
        /// <returns></returns>
        public List<ProggyFileContentModel> GetImagesForFolder(ProggyFileFolderContentModel folder)
        {
            // get images
            var images = folder.GetTypedChildren<ProggyFileContentModel>();

            //
            return images.OrderBy(x => x.OrderInParent).ToList();
        }

        #endregion

        #region properties

        /// <summary>
        /// Image type enum
        /// </summary>
        public bool IsExternalImage { get; set; }

        /// <summary>
        /// If not site image, then the external url
        /// </summary>
        public string ExternalUrl { get; set; }

        /// <summary>
        /// If site image, then the node id
        /// </summary>
        public int? InternalNodeId { get; set; }

        /// <summary>
        /// Alt tag for external
        /// </summary>
        public string ExternalAltTag
        {
            get;
            set;
        }

        /// <summary>
        /// Alt tag for internal
        /// </summary>
        public string InternalAltTag
        {
            get;
            set;
        }

        /// <summary>
        /// Height (optional)
        /// </summary>
        public int? Height { get; set; }

        /// <summary>
        /// Widht (optional)
        /// </summary>
        public int? Width { get; set; }


        #endregion

        #region interface

        public Tuple<bool, string> GetIsValid(System.ComponentModel.DataAnnotations.ValidationContext vContext, ContentModel.ContentModelPropertyTypeAttribute attr)
        {
            if (IsExternalImage && (string.IsNullOrEmpty(ExternalUrl) || string.IsNullOrWhiteSpace(ExternalUrl)))
            {
                return new Tuple<bool, string>(false, "Having selected external url, you must also enter a valid image url");
            }

            if (IsExternalImage && (string.IsNullOrEmpty(ExternalAltTag) || string.IsNullOrWhiteSpace(ExternalAltTag)))
            {
                return new Tuple<bool, string>(false, "Having selected external url, you must also enter a descriptive alt tag");
            }

            if (!IsExternalImage && InternalNodeId == null)
            {
                return new Tuple<bool, string>(false, "Having selected internal image, you must also choose an image");
            }

            return new Tuple<bool, string>(true, "");
        }

        public object GetAutoRenderModel()
        {
            return this;
        }

        [JsonIgnore]
        public string FullPathToAutoRenderPartial
        {
            get { return "~/Areas/ProggyCore/Views/AutoRenderPartials/_ProggyImagePicker.cshtml"; }
        }

        #endregion




    }
}
